#include "stdio.h"
#include "fsl_common.h"
void NMI_Handler(void) {
    printf("NMI_Handler\r\n");
    while(1);
}

void HardFault_Handler(void) {
    printf("HardFault_Handler\r\n");
    while(1);
}

void MemManage_Handler(void) {
    printf("MemManage_Handler\r\n");
    
    uint32_t cfsr_val = (SCB->CFSR);
    
    if (cfsr_val & SCB_CFSR_MMARVALID_Msk) {
        printf("MMFAR has valid contents.\r\n");
    } else {
        printf("MMFAR does not have valid contents.\r\n");
    }
    
    if (cfsr_val & SCB_CFSR_MLSPERR_Msk) {
        printf("A MemManage fault occurred during FP lazy state preservation.\r\n");
    } else {
        printf("No MemManage fault occurred during FP lazy state preservation.\r\n");
    }
    
    if (cfsr_val & SCB_CFSR_MSTKERR_Msk) {
        printf("A derived MemManage fault occurred on exception entry.\r\n");
    } else {
        printf("No derived MemManage fault has occurred.\r\n");
    }
    
    if (cfsr_val & SCB_CFSR_MUNSTKERR_Msk) {
        printf("A derived MemManage fault occurred on exception return.\r\n");
    } else {
        printf("No derived MemManage fault has occurred.\r\n");
    }
    
    if (cfsr_val & SCB_CFSR_DACCVIOL_Msk) {
        printf("Data access violation. The MMFAR shows the data address that the load or store tried to access.\r\n");
    } else {
        printf("No data access violation has occurred.\r\n");
    }
    
    if (cfsr_val & SCB_CFSR_IACCVIOL_Msk) {
        printf("MPU or Execute Never (XN) default memory map access violation on an\r\n");
        printf("instruction fetch has occurred. The fault is signaled only if the instruction is\r\n");
        printf("issued.\r\n");
    } else {
        printf("No MPU or Execute Never (XN) default memory map access violation has occurred.\r\n");
    }
    
    while(1);
}

void BusFault_Handler(void) {
    printf("BusFault_Handler\r\n");
    uint32_t cfsr_val = (SCB->CFSR);
    
    if (cfsr_val & SCB_CFSR_BFARVALID_Msk) {
        printf("BFAR has valid contents.\r\n");
    } else {
        printf("BFAR does not have valid contents.\r\n");
    }
    
    if (cfsr_val & SCB_CFSR_LSPERR_Msk) {
        printf("A bus fault occurred during FP lazy state preservation.\r\n");
    } else {
        printf("No bus fault occurred during FP lazy state preservation.\r\n");
    }
    
    if (cfsr_val & SCB_CFSR_STKERR_Msk) {
        printf("A derived bus fault has occurred on exception entry.\r\n");
    } else {
        printf("No derived bus fault has occurred.\r\n");
    }
    
    if (cfsr_val & SCB_CFSR_UNSTKERR_Msk) {
        printf("A derived bus fault has occurred on exception return.\r\n");
    } else {
        printf("No derived bus fault has occurred.\r\n");
    }
    
    if (cfsr_val & SCB_CFSR_IMPRECISERR_Msk) {
        printf("Imprecise data access error has occurred.\r\n");
    } else {
        printf("No imprecise data access error has occurred.\r\n");
    }
    
    if (cfsr_val & SCB_CFSR_PRECISERR_Msk) {
        printf("A precise data access error has occurred, and the processor has written the faulting address to the BFAR.\r\n");
    } else {
        printf("No precise data access error has occurred.\r\n");
    }
    
    if (cfsr_val & SCB_CFSR_IBUSERR_Msk) {
        printf("A bus fault on an instruction prefetch has occurred. The fault is signaled only if the instruction is issued.\r\n");
    } else {
        printf("No bus fault on an instruction prefetch has occurred.\r\n");
    }
    
    while(1);
}

void UsageFault_Handler(void) {
    printf("UsageFault_Handler\r\n");
    
    uint32_t cfsr_val = (SCB->CFSR);
    
    if (cfsr_val & SCB_CFSR_DIVBYZERO_Msk) {
        printf("Divide by zero error has occurred.\r\n");
    } else {
        printf("No divide by zero error has occurred.\r\n");
    }
    
    if (cfsr_val & SCB_CFSR_UNALIGNED_Msk) {
        printf("Unaligned access error has occurred.\r\n");
    } else {
        printf("No unaligned access error has occurred.\r\n");
    }
    
    if (cfsr_val & SCB_CFSR_NOCP_Msk) {
        printf("A coprocessor access error has occurred. This shows that the coprocessor is disabled or not present.\r\n");
    } else {
        printf("No coprocessor access error has occurred.\r\n");
    }
    
    if (cfsr_val & SCB_CFSR_INVPC_Msk) {
        printf("An integrity check error has occurred on EXC_RETURN.\r\n");
    } else {
        printf("No integrity check error has occurred.\r\n");
    }
    
    if (cfsr_val & SCB_CFSR_INVSTATE_Msk) {
        printf("Instruction executed with invalid EPSR.T or EPSR.IT field.\r\n");
    } else {
        printf("EPSR.T bit and EPSR.IT bits are valid for instruction execution.\r\n");
    }
    
    if (cfsr_val & SCB_CFSR_UNDEFINSTR_Msk) {
        printf("The processor has attempted to execute an undefined instruction.\r\n");
    } else {
        printf("No Undefined Instruction Usage fault has occurred.\r\n");
    }
    
    while(1);
}